﻿using System;
using System.Collections.Generic;
using System.Disposables;
using System.Linq;

namespace RapidDownloader.Model
{
    public sealed class DownloadSubject : ISubject<byte[]>
    {
        #region Fields

        private readonly IDisposable dispose;
        private readonly List<IObserver<byte[]>> observers = new List<IObserver<byte[]>>();

        #endregion

        #region Constructors

        public DownloadSubject()
        {
            dispose = Disposable.Create(() =>
                                            {
                                                observers.Clear();
                                                IsDisposed = true;
                                            });
        }

        #endregion

        #region Properties

        public bool IsDisposed { get; private set; }

        #endregion

        #region Public Methods

        public void OnNext(byte[] value)
        {
            if (!IsDisposed)
                observers.Run(o => o.OnNext(value));
        }

        public void OnCompleted()
        {
            if (!IsDisposed)
            {
                observers.Run(o => o.OnCompleted());
                dispose.Dispose();
            }
        }

        public void OnError(Exception error)
        {
            if (!IsDisposed)
            {
                observers.Run(o => o.OnError(error));
                dispose.Dispose();
            }
        }

        public IDisposable Subscribe(IObserver<byte[]> observer)
        {
            if (IsDisposed)
                return Disposable.Empty;

            observers.Add(observer);
            return dispose;
        }

        #endregion
    }
}